package com.timk.goserver.client.model;

import java.util.Date;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * A game record.
 * @author TKington
 *
 */
public class ClientGameInfo implements IsSerializable {
	private int gameId;
	private int size;
	
	private ClientUserInfo [] players;
	
	private String nextToMove;
	private int handicap;
	private double komi;
	private boolean rated;
	private String sgf;
	private String deadStones;
	private String result;
	private String notes;
	private int moveNumber;
	private int lastInteractiveMove;
	private Date lastMoveTime;
	
	/**
	 * Creates a ClientGameInfo.  Only used for serialization.
	 *
	 */
	public ClientGameInfo() { /* */ }
	
	/**
	 * Creates a ClientGameInfo.
	 * @param size the size
	 * @param players the players
	 * @param nextToMove player whose turn it is
	 * @param handicap
	 * @param komi
	 */
	public ClientGameInfo(int size, ClientUserInfo [] players, String nextToMove,
			int handicap, double komi) {
		this.size = size;
		this.players = players;
		this.nextToMove = nextToMove;
		this.handicap = handicap;
		this.komi = komi;
	}
	
	/**
	 * Returns the color of a given player
	 * @param name the player's name
	 * @return 1 for black, -1 for white
	 */
	public int getColor(String name) {
		for(int i = 0; i < players.length; i++) {
			if(name.equals(players[i].getUsername())) {
				return (i % 2 == 0) ? 1 : -1;
			}
		}
		
		return 0;
	}
	
	/**
	 * Gets the names of the players taking black, separated by spaces
	 * @param buf
	 */
	public void getBlackNames(StringBuffer buf) {
		for(int i = 0; i < players.length; i += 2) {
			if(i > 0) {
				buf.append(' ');
			}
			
			buf.append(players[i].getUsername());
		}
	}
	
	/**
	 * Gets the names of the players taking white, separated by spaces
	 * @param buf
	 */
	public void getWhiteNames(StringBuffer buf) {
		for(int i = 1; i < players.length; i += 2) {
			if(i > 1) {
				buf.append(' ');
			}
			
			buf.append(players[i].getUsername());
		}
	}
	
	/**
	 * Check for a supported handicap configuration
	 * @param size the board size
	 * @param handicap the handicap
	 * @return true if supported
	 */
	public static boolean isValidHandicap(int size, int handicap) {
		switch(size) {
		case 9: return handicap >= 0 && handicap < 6;
		case 13: return handicap >= 0 && handicap < 10;
		case 19: return handicap >= 0 && handicap < 10;
		default: return handicap == 0;
		}
	}
	
	/**
	 * Returns the size of the board
	 * @return the size of the board
	 */
	public int getSize() { return size; }
	
	/**
	 * Sets the board size
	 * @param size
	 */
	public void setSize(int size) { this.size = size; }
	
	/**
	 * Returns the game id
	 * @return the game id
	 */
	public int getGameId() { return gameId; }
	
	/**
	 * Sets the game id
	 * @param gameId
	 */
	public void setGameId(int gameId) { this.gameId = gameId; }
	
	/**
	 * Returns the players
	 * @return the players
	 */
	public ClientUserInfo[] getPlayers() {
		return players;	// NOPMD - Exposing internal array
	}
	
	/**
	 * Sets the players
	 * @param players
	 */
	public void setPlayers(ClientUserInfo [] players) {	// NOPMD - Storing user array
		this.players = players;
	}
	
	/**
	 * Returns the next player to move
	 * @return the next player to move
	 */
	public String getNextToMove() { return nextToMove; }
	
	/**
	 * Sets the next player to move
	 * @param nextToMove
	 */
	public void setNextToMove(String nextToMove) { this.nextToMove = nextToMove; }
	
	/**
	 * Returns the handicap
	 * @return the handicap
	 */
	public int getHandicap() { return handicap; }
	
	/**
	 * Sets the handicap
	 * @param handicap
	 */
	public void setHandicap(int handicap) { this.handicap = handicap; }
	
	/**
	 * Returns the komi
	 * @return the komi
	 */
	public double getKomi() { return komi; }
	
	/**
	 * Sets the komi
	 * @param komi
	 */
	public void setKomi(double komi) { this.komi = komi; }

	/**
	 * Returns the sgf
	 * @return the sgf
	 */
	public String getSgf() {
		return sgf;
	}

	/**
	 * Sets the sgf
	 * @param sgf
	 */
	public void setSgf(String sgf) {
		this.sgf = sgf;
	}

	/**
	 * Returns the dead stones
	 * @return the dead stones
	 */
	public String getDeadStones() {
		return deadStones;
	}

	/**
	 * Sets the dead stones
	 * @param deadStones as a String
	 */
	public void setDeadStones(String deadStones) {
		this.deadStones = deadStones;
	}

	/**
	 * Returns the result
	 * @return the result
	 */
	public String getResult() {
		return result;
	}

	/**
	 * Sets the result
	 * @param result the result
	 */
	public void setResult(String result) {
		this.result = result;
	}

	/**
	 * Returns the notes for the current player
	 * @return the notes for the current player
	 */
	public String getNotes() {
		return notes;
	}

	/**
	 * Sets the notes for the current player
	 * @param notes
	 */
	public void setNotes(String notes) {
		this.notes = notes;
	}

	/**
	 * Returns true if rated
	 * @return true if rated
	 */
	public boolean isRated() {
		return rated;
	}

	/**
	 * Sets whether the game is rated
	 * @param rated
	 */
	public void setRated(boolean rated) {
		this.rated = rated;
	}

	/**
	 * Returns the number of moves played
	 * @return the number of moves played
	 */
	public int getMoveNumber() {
		return moveNumber;
	}

	/**
	 * Sets the number of moves played
	 * @param moveNumber
	 */
	public void setMoveNumber(int moveNumber) {
		this.moveNumber = moveNumber;
	}

	/**
	 * Returns the number of the last move played interactively
	 * @return the number of the last move played interactively
	 */
	public int getLastInteractiveMove() {
		return lastInteractiveMove;
	}

	/**
	 * Sets the number of the last move played interactively
	 * @param lastInteractiveMove
	 */
	public void setLastInteractiveMove(int lastInteractiveMove) {
		this.lastInteractiveMove = lastInteractiveMove;
	}

	/**
	 * Returns the time of the last move
	 * @return the time of the last move
	 */
	public Date getLastMoveTime() {
		return lastMoveTime;
	}

	/**
	 * Sets the time of the last move
	 * @param lastMoveTime
	 */
	public void setLastMoveTime(Date lastMoveTime) {
		this.lastMoveTime = lastMoveTime;
	}
}
